// gulp-clean：用于清理;
// gulp-notify：用于打印消息文本;
// gulp-rename：用于修改名字;
// gulp-concat：用于合并文件;
// gulp-zip：用于生成一个zip压缩包;
// gulp-minify-css：用于压缩css;
// gulp-autoprefixer：用于给css添加前缀;
// gulp-imagemin：用于给图片进行优化;
// gulp-uglify：用于压缩js;
// amd-optimize：用于amd模块引用编译；
// gulp-import-css：如果css文件是通过import导入的可以使用此插件进行合并优化;
// gulp-rev-replace：用于替换;
// gulp-useref：引入使用build标记，进行替换;
// gulp-rev：生成md5文件名;
// gulp-filter：对文件进行过滤;
// gulp-header：压缩之后将注释写入到文件的头部
// gulp-if：进行逻辑判断
// gulp-size：获取文件大小
// gulp-less：编译less文件
// gulp-sass：编译sass文件
// gulp-file-include：对文件进行引入
// gulp-sourcemaps：生成map文件
// gulp-livereload：自动刷新
// gulp-clean-css：css压缩
// browserSync：启动server并启动热更新
// gulp-plumber : 监测工作流，报错，防止遇到错误时直接退出gulp
// gulp-rev : 文件名添加版本号
// gulp-css-spritesmith：根据css文件自动生成雪碧图
const { src, dest, series, parallel, watch } = require('gulp');
const cleanCss = require('gulp-clean-css');
const sass = require('gulp-sass')(require('sass'));
const autoprefixer = require('gulp-autoprefixer');
const imagemin = require('gulp-imagemin');
const babel = require('gulp-babel');
const uglify = require('gulp-uglify');
const gulpCopy = require('gulp-copy');
const clean = require('gulp-clean');
const rename = require('gulp-rename');
const rev = require('gulp-rev');
const revCollector = require('gulp-rev-collector');
const minifyHTML = require('gulp-minify-html');
const fileinclude = require('gulp-file-include');
const notify = require('gulp-notify'); //提示信息
const gulpIf = require('gulp-if');
const csscomb = require('gulp-csscomb');
const prettier = require('gulp-prettier');
const sourcemaps = require('gulp-sourcemaps');
const browserSync = require('browser-sync').create();

let isProd = process.env.NODE_ENV == 'production'; //development,production
console.log('NODE_ENV =', process.env.NODE_ENV);
//编译样式
const compileStyle = () => {
    return src('src/scss/*.scss')
        .pipe(sass())
        .pipe(autoprefixer({ cascade: false, grid: 'autoplace' }))
        .pipe(gulpIf(isProd, cleanCss()))
        .pipe(gulpIf(isProd, rev()))
        .pipe(csscomb())
        .pipe(prettier())
        .pipe(dest('dist/css'))
        .pipe(gulpIf(isProd, rev.manifest('rev-css-manifest.json')))
        .pipe(gulpIf(isProd, dest('dist/rev')));
};

const compileScript = () => {
    return src('src/js/*.js')
        .pipe(babel({ presets: ['@babel/preset-env'] }))
        .pipe(gulpIf(isProd, sourcemaps.init()))
        .pipe(
            gulpIf(
                isProd,
                uglify({
                    mangle: true, //是否修改变量名
                    compress: true, //是否完全压缩
                })
            )
        )
        .pipe(gulpIf(isProd, sourcemaps.write()))
        .pipe(gulpIf(isProd, rev()))
        .pipe(prettier())
        .pipe(dest('dist/js'))
        .pipe(gulpIf(isProd, rev.manifest('rev-js-manifest.json')))
        .pipe(gulpIf(isProd, dest('dist/rev')));
};

const compileHtml = () => {
    return src('src/*.html')
        .pipe(
            fileinclude({
                prefix: '@@',
                basepath: '@file',
            })
        )
        .pipe(gulpIf(isProd, dest('dist/temp')))
        .pipe(gulpIf(!isProd, prettier()))
        .pipe(gulpIf(!isProd, dest('dist')));
};

const compileHtmlAssets = () => {
    return src(['dist/rev/*.json', 'dist/temp/*.html'])
        .pipe(
            revCollector({
                replaceReved: true,
                dirReplacements: {
                    // css: 'css',
                    // js: 'js',
                    // '/js/': './dist/js/',
                    // 'cdn/': function (manifest_value) {
                    //     return '//cdn' + (Math.floor(Math.random() * 9) + 1) + '.' + 'exsample.dot' + '/img/' + manifest_value;
                    // },
                },
            })
        )
        .pipe(
            minifyHTML({
                empty: true,
                spare: true,
            })
        )
        .pipe(dest('dist'));
};

const compileImage = () => {
    return src('src/img/**').pipe(imagemin()).pipe(dest('dist/img'));
};

const copyLibs = () => {
    return src('src/libs/**').pipe(dest('dist/libs'));
};

const copyFavicon = () => {
    return src('src/favicon.ico').pipe(dest('dist'));
};

const copyImage = () => {
    return src('src/img/**').pipe(dest('dist/img'));
};

const cleanStyle = () => {
    return src('dist/css').pipe(clean());
};

const cleanJson = () => {
    return src('dist/rev').pipe(clean());
};

const cleanTemp = () => {
    return src('dist/temp').pipe(clean());
};

const cleanScript = () => {
    return src('dist/js').pipe(clean());
};

const cleanImage = () => {
    return src('dist/img').pipe(clean());
};

const del = (path) => {
    return src(path, {
        allowEmpty: true,
    }).pipe(clean());
};

const cleanAll = () => {
    return src('dist', {
        allowEmpty: true,
    }).pipe(clean());
};

const watching = () => {
    const watcher = watch(['src/**/*.html', 'src/scss/*.scss', 'src/js/*.js', 'src/img/**']);
    watcher.on('change', function (path, stats) {
        console.log(`File ${path} was changed`);
        if (/\.html$/.test(path)) {
            compileHtml();
            browserSync.reload();
        }
        if (/\.scss$/.test(path)) {
            compileStyle();
            browserSync.reload();
        }
        if (/\.js$/.test(path)) {
            compileScript();
            browserSync.reload();
        }
    });

    watcher.on('add', function (path, stats) {
        console.log(`File ${path} was added`);
        if (/\.html$/.test(path)) {
            compileHtml();
            browserSync.reload();
        }
        if (/\.scss$/.test(path)) {
            compileStyle();
            browserSync.reload();
        }
        if (/\.js$/.test(path)) {
            compileScript();
            browserSync.reload();
        }
        if (/\.(png|jpg|jpeg|svg)$/.test(path)) {
            copyImage();
            browserSync.reload();
        }
    });

    watcher.on('unlink', function (path, stats) {
        console.log(`File ${path} was removed`);
        if (/\.(html|js|png|jpg|jpeg|svg)$/.test(path)) {
            del(path.replace('src', 'dist'));
            browserSync.reload();
        }
        if (/\.scss$/.test(path)) {
            del(path.replace(/^src\\scss/, 'dist' + '\\' + 'css').replace(/.scss$/, '.css'));
            browserSync.reload();
        }
        browserSync.reload();
    });
    return watcher;
};

const server = () => {
    browserSync.init({
        server: {
            baseDir: './dist',
        },
        // proxy: {
        //     target: '"http://yourlocal.dev',
        // },
    });

    watching();
};

const dev = series(cleanAll, parallel(compileStyle, compileScript, copyImage, copyLibs, copyFavicon, compileHtml), server);
const build_unpack = series(cleanAll, parallel(compileStyle, compileScript, copyImage, copyLibs, copyFavicon, compileHtml));
const build_compress = series(cleanAll, parallel(compileStyle, compileScript, compileImage, copyLibs, copyFavicon, compileHtml), compileHtmlAssets, cleanJson, cleanTemp);

module.exports = {
    compileStyle,
    compileScript,
    compileHtml,
    compileImage,
    copyImage,
    copyLibs,
    copyFavicon,
    cleanStyle,
    cleanScript,
    cleanImage,
    cleanJson,
    cleanTemp,
    cleanAll,
    server,
    watching,
    dev,
    build_unpack,
    build_compress,
};
